
#include "stdafx.h"
#include <windows.h>

#include "..\..\utils\detours\detours.h"

#include "coolsb_detours.h"
#include "coolscroll.h"

#pragma warning(disable:4100)   // Trampolines don't use formal parameters.

static BOOL (WINAPI *Detour_EnableScrollBar	)(HWND hwnd, UINT wSBflags, UINT wArrows) = EnableScrollBar;
static BOOL (WINAPI *Detour_GetScrollInfo	)(HWND hwnd, int fnBar, LPSCROLLINFO lpsi) =  GetScrollInfo;
static int  (WINAPI *Detour_GetScrollPos	)(HWND hwnd, int nBar) = GetScrollPos;
static BOOL (WINAPI *Detour_GetScrollRange	)(HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos) = GetScrollRange;
static int  (WINAPI *Detour_SetScrollInfo	)(HWND hwnd, int fnBar, LPCSCROLLINFO lpsi, BOOL fRedraw) = SetScrollInfo;
static int  (WINAPI *Detour_SetScrollPos	)(HWND hwnd, int nBar, int nPos, BOOL fRedraw) =  SetScrollPos;
static int  (WINAPI *Detour_SetScrollRange	)(HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL fRedraw) = SetScrollRange;
static BOOL (WINAPI *Detour_ShowScrollBar	)(HWND hwnd, int wBar, BOOL fShow) = ShowScrollBar;

static BOOL WINAPI Tramp_EnableScrollBar(HWND hwnd, int wSBflags, UINT wArrows)
{
	if(CoolSB_IsCoolScrollEnabled(hwnd))	
		return CoolSB_EnableScrollBar(hwnd, wSBflags, wArrows);
	else
		return Detour_EnableScrollBar(hwnd, wSBflags, wArrows);
}

static BOOL WINAPI Tramp_GetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi)
{
	if(CoolSB_IsCoolScrollEnabled(hwnd))	
		return CoolSB_GetScrollInfo(hwnd, fnBar, lpsi);
	else
		return Detour_GetScrollInfo(hwnd, fnBar, lpsi);
}

static int	 WINAPI Tramp_GetScrollPos(HWND hwnd, int nBar)
{
	if(CoolSB_IsCoolScrollEnabled(hwnd))	
		return CoolSB_GetScrollPos(hwnd, nBar);
	else
		return Detour_GetScrollPos(hwnd, nBar);
}

static BOOL WINAPI Tramp_GetScrollRange(HWND hwnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos)
{
	if(CoolSB_IsCoolScrollEnabled(hwnd))	
		return CoolSB_GetScrollRange(hwnd, nBar, lpMinPos, lpMaxPos);
	else
		return Detour_GetScrollRange(hwnd, nBar, lpMinPos, lpMaxPos);
}

static int	 WINAPI Tramp_SetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw)
{
	if(CoolSB_IsCoolScrollEnabled(hwnd))	
		return CoolSB_SetScrollInfo(hwnd, fnBar, lpsi, fRedraw);
	else
		return Detour_SetScrollInfo(hwnd, fnBar, lpsi, fRedraw);
}

static int  WINAPI Tramp_SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL fRedraw)
{
	if(CoolSB_IsCoolScrollEnabled(hwnd))	
		return CoolSB_SetScrollPos(hwnd, nBar, nPos, fRedraw);
	else
		return Detour_SetScrollPos(hwnd, nBar, nPos, fRedraw);
}

static int  WINAPI Tramp_SetScrollRange(HWND hwnd, int nBar, int nMinPos, int nMaxPos, BOOL fRedraw)
{
	if(CoolSB_IsCoolScrollEnabled(hwnd))	
		return CoolSB_SetScrollRange(hwnd, nBar, nMinPos, nMaxPos, fRedraw);
	else
		return Detour_SetScrollRange(hwnd, nBar, nMinPos, nMaxPos, fRedraw);
}

static BOOL WINAPI Tramp_ShowScrollBar		(HWND hwnd, int wBar, BOOL fShow)
{
	if(CoolSB_IsCoolScrollEnabled(hwnd))	
		return CoolSB_ShowScrollBar(hwnd, wBar, fShow);
	else
		return Detour_ShowScrollBar(hwnd, wBar, fShow);
}

BOOL WINAPI CoolSB_InitializeApp(void)
{
	DWORD dwVersion = GetVersion();

	// Only available under Windows NT, 2000 and XP
	if(dwVersion < 0x80000000)
	{
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		DetourAttach(&(PVOID&)Detour_EnableScrollBar, Tramp_EnableScrollBar);
		DetourAttach(&(PVOID&)Detour_GetScrollInfo, Tramp_GetScrollInfo);
		DetourAttach(&(PVOID&)Detour_GetScrollPos, Tramp_GetScrollPos);
		DetourAttach(&(PVOID&)Detour_GetScrollRange, Tramp_GetScrollRange);
		DetourAttach(&(PVOID&)Detour_SetScrollInfo, Tramp_SetScrollInfo);
		DetourAttach(&(PVOID&)Detour_SetScrollPos, Tramp_SetScrollPos);
		DetourAttach(&(PVOID&)Detour_SetScrollRange, Tramp_SetScrollRange);
		DetourAttach(&(PVOID&)Detour_ShowScrollBar, Tramp_ShowScrollBar);
		DetourTransactionCommit();

		CoolSB_SetESBProc(Detour_EnableScrollBar);

		return TRUE;
	}
	else
	{
		return FALSE;
	}	
}

BOOL WINAPI CoolSB_UninitializeApp(void)
{
	DWORD dwVersion = GetVersion();

	// Only available under Windows NT, 2000 and XP
	if(dwVersion < 0x80000000)
	{
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		DetourDetach(&(PVOID&)Detour_EnableScrollBar, Tramp_EnableScrollBar);
		DetourDetach(&(PVOID&)Detour_GetScrollInfo, Tramp_GetScrollInfo);
		DetourDetach(&(PVOID&)Detour_GetScrollPos, Tramp_GetScrollPos);
		DetourDetach(&(PVOID&)Detour_GetScrollRange, Tramp_GetScrollRange);
		DetourDetach(&(PVOID&)Detour_SetScrollInfo, Tramp_SetScrollInfo);
		DetourDetach(&(PVOID&)Detour_SetScrollPos, Tramp_SetScrollPos);
		DetourDetach(&(PVOID&)Detour_SetScrollRange, Tramp_SetScrollRange);
		DetourDetach(&(PVOID&)Detour_ShowScrollBar, Tramp_ShowScrollBar);
		DetourTransactionCommit();

		// don't actually use this feature within coolsb yet, but we might need it
		CoolSB_SetESBProc(EnableScrollBar);

		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
